<!--
 * @description: 
 * @Author: jhw
 * @Date: 2023-05-20 11:42:07
 * @LastEditors: jhw
 * @LastEditTime: 2023-05-21 00:43:17
-->
<template>
  <div>
    <div style="border: 1px solid #ccc">
      <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :default-config="toolbarConfig" :mode="mode" />
      <Editor
        v-model="valueHtml"
        :style="styles"
        style="overflow-y: hidden"
        :default-config="editorConfig"
        :mode="mode"
        @onCreated="handleCreated"
        @onChange="handleChange"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css'; // 引入 css

import { onBeforeUnmount, ref, shallowRef, computed, watch, nextTick } from 'vue';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import { IToolbarConfig } from '@wangeditor/editor';
import '@/utils/editor';
// import { ElMessage } from 'element-plus';
const props = defineProps({
  // 编辑器内容html
  editorHtmlValue: {
    type: String,
    default: '',
  },
  // 编辑器内容text
  editorTextValue: {
    type: String,
    default: '',
  },
  /* 高度 */
  height: {
    type: Number,
    default: 500,
  },
  /* 最小高度 */
  minHeight: {
    type: Number,
    default: 500,
  },
  /* 只读 */
  readOnly: {
    type: Boolean,
    default: false,
  },
});

const emits = defineEmits(['update:editorHtmlValue', 'update:editorTextValue']);

const styles = computed(() => {
  return {
    height: `${props.height}px`,
    minHeight: `${props.minHeight}px`,
  };
});

watch(
  [() => props.editorHtmlValue, () => props.readOnly],
  ([_editorHtmlValue, _readOnly]) => {
    nextTick(() => {
      const editor = editorRef.value;
      if (editor == null) return;
      editor.setHtml(_editorHtmlValue);
      editor.getConfig().readOnly = _readOnly;
    });
  },
  {
    immediate: true,
    deep: true,
  },
);

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef();

// 内容 HTML
const valueHtml = ref('');

const mode = 'default'; // 或 'simple'

const toolbarConfig: Partial<IToolbarConfig> = {
  insertKeys: {
    index: 100,
    keys: ['uploadAttachment'],
  },
  excludeKeys: ['group-video'],
};
const editorConfig = {
  placeholder: '请输入内容...',
  hoverbarKeys: {
    attachment: {
      menuKeys: ['downloadAttachment'], // “下载附件”菜单
    },
  },
  MENU_CONF: {
    uploadImage: {
      server: '/api/io/upload',
      fieldName: 'file',
      meta: {
        token: localStorage.getItem('token'),
      },
      onSuccess(file: File, res: any) {
        console.log(file, res, 'file, res');
      },
      onFailed: (file: File, res: any) => {
        console.log(file, res, 'file, res');
      },
      onError(file: File, err: Error, res: any) {
        console.log(file, err, res, 'file, err, res');
      },
      customInsert: (res: { data: any }, insertFn: (arg0: any) => void) => {
        let url = res.data;
        insertFn(url);
      },
    },
    uploadAttachment: {
      server: '/api/io/upload',
      fieldName: 'file',
      meta: { token: localStorage.getItem('token') },

      onBeforeUpload(file: File) {
        console.log(file, 'file, 上传文件判断格式等等');
      },
      onFailed(file: File, res: any) {
        console.log(file, res, 'file, res');
        throw new Error('上传失败');
      },
      onError(file: File, err: Error, res: any) {
        console.log(file, err, res, 'file, err, res');
      },
      // // 用户自定义插入文件
      customInsert(res: any, file: File, insertFn: (arg0: string, arg1: any) => void) {
        const { data } = res || {};
        if (!data) throw new Error(`file is empty`);
        // 自己插入附件
        insertFn(`${file.name}`, data);
      },
    },
  },
};

const handleCreated = (editor: any) => {
  editorRef.value = editor; // 记录 editor 实例，重要！
};

// 内容改变时触发
const handleChange = () => {
  emits('update:editorHtmlValue', valueHtml.value);
  emits('update:editorTextValue', editorRef.value?.getText());
  // 给内容设置行高
  // console.log(editor.children, 'editor.children');
  // editor.children.forEach((item: any) => {
  //   console.log(item);
  // });
};

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});
</script>

<style scoped></style>
